home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
gnu
/
progutil
/
stdwin.zoo
/
atari
/
menu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-29
|
11KB
|
618 lines
#include "window.h"
#include "trees.h"
#include "atari_proto.h"
#undef P
static int deflocal = FALSE ;
static struct menubar globmenus ;
static int barchanged = FALSE ;
static struct ln m_link[256] ;
static OBJECT *menu = NULL ;
extern int scr_width ;
extern int scr_height ;
extern WINDOW **winlist ;
extern WINDOW *active ;
extern int nrwin ;
void
initmbar (win)
WINDOW *win ;
{
int i ;
L_INIT (win->mbar.nrmenus, win->mbar.menulist) ;
for (i = 0 ; i < globmenus.nrmenus ; i++)
wmenuattach (win, globmenus.menulist[i]) ;
}
void
initglobmenus ()
{
MENU *pm ;
int i ;
L_INIT (globmenus.nrmenus, globmenus.menulist) ;
wmenusetdeflocal (FALSE) ;
pm = wmenucreate (0, "Desk") ;
(void) wmenuadditem (pm, "About STDWIN...", -1) ;
(void) wmenuadditem (pm, "", -1) ;
for (i = 0 ; i < 6 ; i++)
(void) wmenuadditem (pm, "Desk Acc. Slot", -1) ;
}
void
addtobar (pbar, pm)
struct menubar *pbar ;
MENU *pm ;
{
int i ;
for (i = 0 ; i < pbar->nrmenus ; i++) {
if (pbar->menulist[i] == pm)
return ;
}
L_APPEND (pbar->nrmenus, pbar->menulist, MENU *, pm) ;
}
void
delofbar (pbar, pm)
struct menubar *pbar ;
MENU *pm ;
{
int i ;
for (i = 0 ; i < pbar->nrmenus ; i++) {
if (pbar->menulist[i] == pm) {
L_REMOVE (pbar->nrmenus, pbar->menulist, MENU *, i) ;
break ;
}
}
}
void
addtoall (pm)
MENU *pm ;
{
int i ;
addtobar (&globmenus, pm) ;
for (i = 0 ; i < nrwin ; i++)
wmenuattach (winlist[i], pm) ;
}
MENU
*wmenucreate (id, title)
int id ;
char *title ;
{
MENU *pm ;
char buf[20] ;
pm = ALLOC (MENU) ;
if (pm == NULL)
return (NULL) ;
pm->id = id ;
sprintf (buf, " %s ", title) ;
pm->title = strdup (buf) ;
pm->local = deflocal ;
pm->maxlen = 0 ;
L_INIT (pm->nritems, pm->itemlist) ;
if (!pm->local)
addtoall (pm) ;
return (pm) ;
}
void
wmenusetdeflocal (flag)
int flag ;
{
deflocal = flag ;
}
void
wmenuattach (win, pm)
WINDOW *win ;
MENU *pm ;
{
addtobar (&win->mbar, pm) ;
if (win == active)
barchanged = TRUE ;
}
void
wmenudetach (win, pm)
WINDOW *win ;
MENU *pm ;
{
delofbar (&win->mbar, pm) ;
if (win == active)
barchanged = TRUE ;
}
void
wmenudelete (pm)
MENU *pm ;
{
int i ;
delofbar (&globmenus, pm) ;
for (i = 0 ; i < nrwin ; i++)
wmenudetach (winlist[i], pm) ;
for (i = 0 ; i < pm->nritems ; i++) {
FREE (pm->itemlist[i]->ittext) ;
FREE (pm->itemlist[i]->sctext) ;
FREE (pm->itemlist[i]->line) ;
}
L_DEALLOC (pm->nritems, pm->itemlist) ;
FREE (pm) ;
}
int
wmenuadditem (pm, str, shortcut)
MENU *pm ;
char *str ;
int shortcut ;
{
struct m_item *it = ALLOC (struct m_item) ;
int len = 0 ;
char buf[50] ;
barchanged = TRUE ;
it->ittext = strdup (str) ;
it->checked = FALSE ;
it->enabled = str != NULL && *str != 0 ;
if (it->enabled)
len = 2 + (int)strlen (it->ittext) ;
if (shortcut > -1) {
sprintf (buf, "Alt-%c", shortcut) ;
it->sctext = strdup (buf) ;
setkey (pm->id, pm->nritems, shortcut) ;
len += (2 + (int)strlen (it->sctext)) ;
}
else
it->sctext = NULL ;
it->line = NULL ;
L_APPEND (pm->nritems, pm->itemlist, struct m_item *, it) ;
if (++len > pm->maxlen)
pm->maxlen = len ;
pm->dirty = TRUE ;
return (pm->nritems - 1) ;
}
void
wmenusetitem (pm, item, text)
MENU *pm ;
int item ;
char *text ;
{
struct m_item *it ;
int len = 0 ;
if (item < 0 || item >= pm->nritems)
return ;
it = pm->itemlist[item] ;
FREE (it->ittext) ;
pm->dirty = TRUE ;
it->enabled = text != NULL && *text != 0 ;
if (it->enabled) {
it->ittext = strdup (text) ;
len = 2 + (int)strlen (it->ittext) ;
if (it->sctext != NULL || *it->sctext != '\0')
len += 2 + (int)strlen (it->sctext) ;
}
else
it->checked = FALSE ;
if (++len > pm->maxlen)
pm->maxlen = len ;
barchanged = TRUE ;
}
void
wmenuenable (pm, item, flag)
MENU *pm ;
int item ;
bool flag ;
{
struct m_item *it ;
if (item < 0 || item >= pm->nritems)
return ;
it = pm->itemlist[item] ;
if (it->enabled == flag)
return ;
it->enabled = flag ;
if (menu != NULL) {
int obj = 4 ;
int i ;
for (i = 0 ; i < active->mbar.nrmenus ; ++i) {
MENU *mp = active->mbar.menulist[i] ;
if (pm == mp)
break ;
obj += mp->nritems + 1 ;
}
obj += item + 1 + active->mbar.nrmenus ;
menu_ienable (menu, obj, it->enabled) ;
}
}
void
wmenucheck (pm, item, flag)
MENU *pm ;
int item ;
bool flag ;
{
struct m_item *it ;
if (item < 0 || item >= pm->nritems)
return ;
it = pm->itemlist[item] ;
if (it->checked == flag)
return ;
it->checked = flag ;
if (menu != NULL) {
int obj = 4 ;
int i ;
for (i = 0 ; i < active->mbar.nrmenus ; ++i) {
MENU *mp = active->mbar.menulist[i] ;
if (pm == mp)
break ;
obj += mp->nritems + 1 ;
}
obj += item + 1 + active->mbar.nrmenus ;
menu_icheck (menu, obj, it->checked) ;
}
}
OBJECT
*buildbar (win)
WINDOW *win ;
{
TREE tree = { 0, 0, 0 } ;
TREE *t = &tree ;
int act ;
int scr ;
int box ;
int title ;
int dummy = 0 ;
int lh = wlineheight () ;
int first = 1 ;
int act_x = 2 * wcharwidth ('m') ;
int m_width = 0 ;
int s_height = 0 ;
int i ;
int j ;
tr_add (t, 0, G_IBOX, NONE, NORMAL, 0L, 0, 0, scr_width, scr_height) ;
m_link[t->focus].m = m_link[t->focus].it = -1 ;
tr_add (t, 1, G_BOX, NONE, NORMAL, BAR, 0, 0, scr_width, BAR_HEIGHT) ;
m_link[t->focus].m = m_link[t->focus].it = -1 ;
tr_add (t, 1, G_IBOX, NONE, NORMAL, 0L, act_x, 0,
dummy, BAR_HEIGHT) ;
act = t->focus ;
m_link[t->focus].m = m_link[t->focus].it = -1 ;
for (i = 0 ; i < win->mbar.nrmenus ; i++) {
int width ;
MENU *pm = win->mbar.menulist[i] ;
width = wtextwidth (pm->title, -1) ;
tr_add (t, first, G_TITLE, NONE, NORMAL, pm->title, m_width, 0,
width, BAR_HEIGHT) ;
m_width += width ;
m_link[t->focus].m = pm->id ;
m_link[t->focus].it = -1 ;
if (first)
first = 0 ;
}
t->obj[act].ob_width = m_width ;
tr_parent (t) ;
tr_parent (t) ;
tr_add (t, 0, G_IBOX, NONE, NORMAL, 0L, 0, BAR_HEIGHT, scr_width,
dummy) ;
scr = t->focus ;
m_link[t->focus].m = m_link[t->focus].it = -1 ;
first = 1 ;
title = t->obj[act].ob_head ;
for (i = 0 ; i < win->mbar.nrmenus ; i++) {
int firstit = 1 ;
int b_width = 0 ;
int box_x = t->obj[title].ob_x + t->obj[act].ob_x ;
MENU *pm = win->mbar.menulist[i] ;
if (pm->dirty)
checkmenu (pm) ;
tr_add (t, first, G_BOX, NONE, NORMAL, BOX, box_x, 0,
dummy, dummy) ;
box = t->focus ;
m_link[t->focus].m = m_link[t->focus].it = -1 ;
for (j = 0 ; j < pm->nritems ; j++) {
struct m_item *it = pm->itemlist[j] ;
int width = wtextwidth (it->line, -1) ;
int state = (it->enabled ? NORMAL : DISABLED) ;
if (it->checked)
state |= CHECKED ;
tr_add (t, firstit, G_STRING, NONE, (long)state, it->line, 0,
j * lh, width, lh) ;
if (width > b_width)
b_width = width ;
m_link[t->focus].m = pm->id ;
m_link[t->focus].it = j ;
if (firstit)
firstit = 0 ;
}
if (!firstit)
tr_parent (t) ;
for (j = 0 ; j < pm->nritems ; j++) {
OBJECT *o = &t->obj[t->focus + j + 1] ;
o->ob_width = b_width ;
}
t->obj[box].ob_width = b_width ;
t->obj[box].ob_height = pm->nritems * lh ;
if (t->obj[box].ob_height > s_height )
s_height = t->obj[box].ob_height ;
if (first)
first = 0 ;
title = t->obj[title].ob_next ;
}
t->obj[scr].ob_height = s_height ;
/* tr_dump (t) ;
*/ return (tr_tree (t)) ;
}
void
checkmenu (pm)
MENU *pm ;
{
int k ;
for (k = 0 ; k < pm->nritems ; k++) {
struct m_item *i = pm->itemlist[k] ;
char buf[256] ;
char *cp = buf ;
char *text = i->ittext ;
int l ;
if (i->line != NULL && (int)strlen (i->line) == pm->maxlen)
continue ;
FREE (i->line) ;
if (text == NULL)
text = "" ;
if (*text == '\0') {
for (l = 0 ; l < pm->maxlen ; ++l)
*cp++ = '-' ;
*cp = '\0' ;
}
else {
l = 2 + (int)strlen (text) ;
sprintf (cp, " %s", text) ;
cp += l ;
text = i->sctext ;
if (text != NULL) {
l += (int)strlen (text) ;
while (l < pm->maxlen - 1) {
++l ;
*cp++ = ' ' ;
}
strcpy (cp, text) ;
cp += (int)strlen (cp) ;
}
strcat (cp, " ") ;
}
i->line = strdup (buf) ;
}
pm->dirty = FALSE ;
}
void
menuupda